<template> 
	<div class="app-container">
		<div class="margin-bottom20">角色权限</div>
		<div class="row-me flex-end">
			<el-button class="btn-add" @click="handleUpdateRole(0,{})" size="mini" type="primary">
				新增角色
			</el-button>
		</div>
		<div class="table-container">
			<el-table ref="orderTable" :data="list" style="width: 100%;" @selection-change="handleSelectionChange"
				v-loading="listLoading" border>
				<el-table-column type="selection" width="40" align="center"></el-table-column>
				<el-table-column label="ID" width="70" align="center">
					<template slot-scope="scope">{{scope.row.id}}</template>
				</el-table-column>
				<el-table-column label="角色名" align="center">
					<template slot-scope="scope">{{scope.row.name}}</template>
				</el-table-column>
				<el-table-column label="是否系统角色" align="center">
					<template slot-scope="scope">
						<el-switch :active-value="true" :inactive-value="false" :disabled="true" v-model="scope.row.isDefaultRole">
						</el-switch>
					</template>
				</el-table-column>
				<el-table-column label="备注" align="center">
					<template slot-scope="scope">{{scope.row.remark}}</template>
				</el-table-column>
				<el-table-column label="操作" width="" align="center">
					<template slot-scope="scope">
						<el-button :disabled="scope.row.isDefaultRole" size="mini"
							@click="handleUpdateRole(scope.$index, scope.row)">编辑
						</el-button>
						<el-button :disabled="scope.row.isDefaultRole" size="mini"
							@click="handleUpdateRolePermission(scope.$index, scope.row)">分配权限
						</el-button>
						<el-button :disabled="scope.row.isDefaultRole" size="mini" type="danger"
							@click="handleDeleteRole(scope.$index, scope.row)">删除
						</el-button>
					</template>
				</el-table-column>
			</el-table>
		</div>
		<div class="pagination-container">
			<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
				layout="total, sizes,prev, pager, next,jumper" :current-page.sync="listQuery.pageNumber"
				:page-size="listQuery.pageSize" :page-sizes="[5,10,15]" :total="total">
			</el-pagination>
		</div>
		<!-- 新增编辑角色 -->
		<el-dialog :title="title" :visible.sync="visible" width="30%" top="5vh" :destroy-on-close="true">
			<el-form :model="form" ref="form" label-width="100px">
				<el-form-item label="角色名称:">
					<el-input class="width400" placeholder="请输入角色名称" v-model="form.name"></el-input>
				</el-form-item>
				<el-form-item label="角色顺序:">
					<el-input class="width400" placeholder="请输入角色顺序" v-model="form.sort"></el-input>
				</el-form-item>
				<el-form-item label="状态:">
					<el-radio v-model="form.isLocked" :label="1">正常</el-radio>
					<el-radio v-model="form.isLocked" :label="0">禁用</el-radio>
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="visible = false">取 消</el-button>
					<el-button @click="submitForm" type="primary">确 认</el-button>
				</span>
			</template>
		</el-dialog>
		<!-- 编辑角色权限 -->
		<el-dialog title="角色权限编辑" :visible.sync="editPermissionVisible" top="5vh">
			<template>
				<el-card class="" shadow="never">
					<div v-for="(per,index) in permissions" :class="index===0?'top-line':null" :key="'per'+per.id">
						<el-row class="table-layout" style="background: #F2F6FC;">
							<el-checkbox v-model="per.checked" @change="handleCheckAllChange(per)">
								<!--                           :indeterminate="isIndeterminate(per.id)"-->
								{{per.name}}
							</el-checkbox>
						</el-row>
						<el-row class="table-layout">
							<el-col :span="8" v-for="child in per.children" :key="'child'+child.id" style="padding: 4px 0">
								<el-checkbox v-model="child.checked" @change="handleCheckChange(child)">
									{{child.name}}
								</el-checkbox>
							</el-col>
						</el-row>
					</div>
					<div style="margin-top: 20px" align="center">
						<el-button type="primary" @click="handleSave()">保存</el-button>
						<el-button @click="handleClear()">清空</el-button>
					</div>
				</el-card>
			</template>
		</el-dialog>
	</div>
</template>

<script>
	import {
		fetchRoleList,
		deleteRole,
		getAllPermission,
		updateRolePermission,
		getRolePermission
	} from '@/api/role'
	import {
		formatDate
	} from '@/utils/date';

	const defaultListQuery = {
		pageNumber: 1,
		pageSize: 10,
		name: null,
	};
	export default {
		name: "adminUserList",
		data() {
			return {
				listQuery: Object.assign({}, defaultListQuery),
				listLoading: true,
				list: null,
				total: null,
				operateType: null,
				editPermissionVisible: false,
				multipleSelection: [],
				permissions: [],
				editPermission: {
					roleId: '',
					permissionIds: []

				},
				operateOptions: [{
					label: "批量删除",
					value: 3
				}],
				logisticsDialogVisible: false,
				form: {},
				title: '',
				visible: false
			}
		},
		created() {
			this.getList();
			this.getPermissionList();
		},
		filters: {
			formatCreateTime(time) {
				let date = new Date(time);
				return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
			},
			formatStatus(value) {
				if (value === 0) {
					return '正常';
				} else if (value === 1) {
					return '暂停';
				}
			},
		},
		methods: {
			async submitForm() {
				if (this.$.isEmpty(this.form.name)) {
					this.$message.warning('请输入角色名称!')
					return
				}
				const res = await this.$post('/admin/role/update', this.form)
				if (res.code == 1000) {
					this.$message.success('操作成功')
					this.getList()
					this.visible = false
				}
			},
			isIndeterminate(parentId) {
				let child = this.getChild(parentId);
				if (child == null) return false;
				let checkedCount = 0;
				for (let i = 0; i < child.length; i++) {
					if (child[i].checked === true) {
						checkedCount++;
					}
				}
				return !(checkedCount === 0 || checkedCount === child.length);
			},
			isChildChecked(childId, allocPermission) {
				if (allocPermission.id === childId) {
					return true;
				}
				return false;
			},
			isHasChecked(parentId) {
				let child = this.getChild(parentId);
				if (child == null) return false;
				let checkedCount = 0;
				for (let i = 0; i < child.length; i++) {
					if (child[i].checked === true) {
						checkedCount++;
					}
				}
				if (checkedCount === 0) {
					return false;
				}
				return checkedCount > 0;
			},
			isAllChecked(parentId) {
				let child = this.getChild(parentId);
				if (child == null) return false;
				let checkedCount = 0;
				for (let i = 0; i < child.length; i++) {
					if (child[i].checked === true) {
						checkedCount++;
					}
				}
				if (checkedCount === 0) {
					return false;
				}
				return checkedCount === child.length;
			},
			getChild(parentId) {
				let child = [];
				if (this.permissions == null) return null;
				for (let i = 0; i < this.permissions.length; i++) {
					let resource = this.permissions[i];
					if (resource.id === parentId) {
						child = resource.children;
					}
				}
				return child;
			},

			handleSave() {
				this.$confirm('是否分配权限？', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					let checkedIds = [];
					if (this.permissions != null && this.permissions.length > 0) {
						this.permissions.forEach(item => {
							if (item.checked) {
								checkedIds.push(item.id);
							}
							checkedIds.push(this.buildSubmitCheck(item));
						});
					}
					this.editPermission.permissionIds = checkedIds;
					updateRolePermission(this.editPermission).then(response => {
						this.$message({
							message: '分配成功',
							type: 'success',
							duration: 1000
						});
					})
				}, () => {})
			},

			buildSubmitCheck(parent) {
				let vm = this;
				let check = [];
				if (parent.children != null && parent.children.length > 0) {
					for (let i = 0; i < parent.children.length; i++) {
						if (parent.children[i].checked) {
							check.push(parent.children[i].id)
						}
						check.push(vm.buildSubmitCheck(parent.children[i]));
					}
				}
				return check;
			},

			handleClear() {
				let vm = this;
				this.permissions.forEach(item => {
					item.checked = false;
					vm.clearChildCheck(item);
				})
				this.$forceUpdate();
			},
			clearChildCheck(parent) {
				let vm = this;
				if (parent.children != null && parent.children.length > 0) {
					for (let i = 0; i < parent.children.length; i++) {
						parent.children[i].checked = false;
						vm.clearChildCheck(parent.children[i]);
					}
				}
			},
			handleCheckAllChange(parent) {
				let child = this.getChild(parent.id);
				for (let i = 0; i < child.length; i++) {
					child[i].checked = parent.checked;
				}
				this.$forceUpdate();
			},
			handleCheckChange(child) {
				this.permissions.forEach(item => {
					if (item.id === child.parentId) {
						item.checked = this.isHasChecked(child.parentId);
					}
				});
				this.$forceUpdate();
			},


			handleUpdateRole(index, row) {
				if (row.id) {
					this.title = '编辑角色'
					this.form = JSON.parse(JSON.stringify(row))
				} else {
					this.title = '新增角色'
					this.form = {}
				}
				this.visible = true
			},
			handleUpdateRolePermission(index, row) {
				for (let item of this.permissions) {
					item.checked = false
					if (item.children && item.children.length != 0) {
						for (let val of item.children) {
							val.checked = false
						}
					}
				}
				this.editPermissionVisible = true;
				this.editPermission.roleId = row.id;
				this.getAllocPermissionList(row.id);

			},
			handleAddRole() {
				this.$router.push({
					path: '/schedule/update'
				})
			},
			handleResetSearch() {
				this.listQuery = Object.assign({}, defaultListQuery);
			},
			handleSearchList() {
				this.listQuery.pageNumber = 1;
				this.getList();
			},
			handleSelectionChange(val) {
				this.multipleSelection = val;
			},
			handleDeleteRole(index, row) {
				let ids = [];
				ids.push(row.id);
				this.deleteRole(ids);
			},
			handleBatchOperate() {
				if (this.multipleSelection == null || this.multipleSelection.length < 1) {
					this.$message({
						message: '请选择要操作的数据',
						type: 'warning',
						duration: 1000
					});
					return;
				}
				if (this.operateType === 3) {
					//批量删除
					let ids = [];
					for (let i = 0; i < this.multipleSelection.length; i++) {
						ids.push(this.multipleSelection[i].id);
					}
					this.deleteRole(ids);
				}
			},
			handleSizeChange(val) {
				this.listQuery.pageNumber = 1;
				this.listQuery.pageSize = val;
				this.getList();
			},
			handleCurrentChange(val) {
				this.listQuery.pageNumber = val;
				this.getList();
			},
			getList() {
				this.listLoading = true;
				fetchRoleList(this.listQuery).then(response => {
					this.listLoading = false;
					this.list = response.data.list;
					this.total = response.data.totalPage;
				});
			},
			getPermissionList() {
				getAllPermission().then(response => {
					this.permissions = response.data;
				});
			},
			getAllocPermissionList(roleId) {
				let vm = this;
				getRolePermission(roleId).then(response => {
					let allocPermissions = response.data;
					vm.handleAlloc(allocPermissions);

				});
			},

			handleAlloc(allocPermissions) {
				let vm = this;
				allocPermissions.forEach(alloc => {
					vm.permissions.forEach(item => {
						vm.handleAllocChild(item, alloc);
					})
				})
				this.$forceUpdate();
			},
			handleAllocChild(parent, alloc) {
				let vm = this;
				if (!parent.checked) {
					parent.checked = vm.isChildChecked(parent.id, alloc);
				}
				if (parent.children != null && parent.children.length > 0) {
					for (let i = 0; i < parent.children.length; i++) {
						vm.handleAllocChild(parent.children[i], alloc);
					}
				}
			},


			deleteRole(ids) {
				this.$confirm('是否要进行该删除操作?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					deleteRole(ids).then(response => {
						this.$message({
							message: '删除成功！',
							type: 'success',
							duration: 1000
						});
						this.getList();
					});
				}, () => {})
			}
		}
	}
</script>
<style scoped>
	.input-width {
		width: 203px;
	}

	.table-layout {
		padding: 20px;
		border-left: 1px solid #DCDFE6;
		border-right: 1px solid #DCDFE6;
		border-bottom: 1px solid #DCDFE6;
	}

	.top-line {
		border-top: 1px solid #DCDFE6;
	}
</style>